package services;

import br.com.caelum.vraptor.ioc.Component;
import entities.ProductStatus;
import entities.ProductType;
import entities.ProductsEntity;
import entities.UsersEntity;
import logs.LogManager;
import managers.ProductsManager;
import managers.UserManager;
import managers.WrongBidException;
import managers.WrongProductException;
import models.ProductImport;
import models.ProductImportList;

import java.sql.Timestamp;

@Component
public class ProductsService {
    private ProductsManager productsManager;
    private UserManager userManager;

    public ProductsManager getProductsManager() {
        return productsManager;
    }

    public ProductsService(ProductsManager productsManager, UserManager userManager) {
        this.productsManager = productsManager;
        this.userManager = userManager;
    }

    public void placeBid(int productId, String username, float price) throws WrongBidException {
        UsersEntity user = userManager.getUsersData(username);
        ProductsEntity product = productsManager.getProductById(productId);

        if(product.getMinPrice() > price){
            throw new WrongBidException("Price need to be at least " + product.getMinPrice());
        }

        if(product.getType() == ProductType.AUCTION){
            Float maxBid = productsManager.getMaxBid(productId);
            if(maxBid != null && maxBid >= price){
                throw new WrongBidException("Price need to be greater than " + maxBid);
            }
        }

        productsManager.placeBid(product.getId(), user.getUserId(), price);

        LogManager.logForProduct(product.getId()).write("Bid set by user:", user.getUserId(), " Price:", price);
        LogManager.logForUser(user.getUserId()).write("Bid set for product:", product.getName(), " Price:", price);
    }

    public void closeAuction(int productId){
        productsManager.updateProductStatus(productId, ProductStatus.ENDED);
        Float maxBid = productsManager.getMaxBid(productId);
        if(maxBid == null)
            maxBid = 0F;

        LogManager.logForProduct(productId).write("Product closed. Max Bid: ", maxBid);
        LogManager.logForProduct(0).write("Product", productId ,"closed. Max Bid: ", maxBid);
    }

    public void saveProduct(ProductsEntity product) throws WrongProductException {
        if(product.getType() != ProductType.AUCTION && product.getType() != ProductType.TENDER)
            throw new WrongProductException("Wrong product type");

        if(product.getName() == null || product.getName() == "")
            throw new WrongProductException("Product name is empty");

        if(product.getDateEnd() == null && product.getType() == ProductType.TENDER)
            throw new WrongProductException("Closing Date need to be provided for tenders");

        if(product.getType() == ProductType.AUCTION && product.getDateEnd() != null){
            product.setDateEnd(null);
        }

        productsManager.saveProduct(product);

        LogManager.logForProduct(product.getId()).write("Product Created");
        LogManager.logForProduct(0).write("Product", product.getId() ,"created");
    }

    public void saveProductsFromImportedList(ProductImportList list) throws WrongProductException {
        if(list != null && list.getList().size() > 0){
            for(ProductImport pr : list.getList()){
                ProductsEntity entity = new ProductsEntity();
                entity.setName(pr.getName());
                entity.setDescription(pr.getDescription());
                if(pr.getDateEnd() != null){
                    entity.setDateEnd(new Timestamp(pr.getDateEnd().getTime()));
                }
                entity.setMinPrice(pr.getMinPrice());
                entity.setType(pr.getType());
                entity.setStatus(ProductStatus.NORMAL);

                saveProduct(entity);
            }
        }
    }
}
